package dryven.unittest.mocks;

import java.lang.reflect.Method;

import dryven.reflection.DeclaringMethodIterator;
import dryven.request.controller.ControllerDescription;
import dryven.request.controller.paramtransform.baseimpl.PrimitiveTypeBinder;
import dryven.request.http.Request;
import dryven.request.http.Response;
import dryven.request.routing.RoutingService;

public class MockRoutingService implements RoutingService {

	@Override
	public String controllerToRoute(ControllerDescription cd) {
		String baseUrl = cd.getControllerClass().getName().replace('.', '/')+"."+cd.getAction().getName()+"#";
		StringBuffer buf = new StringBuffer();
		int i = 0;
		for (Class<?> type : cd.getAction().getParameterTypes()) {
			Object value = cd.getActionParameter(i);
			++i;
			buf.append(value==null?"null":value.toString());
			buf.append(",");
		}
		if(buf.length()!=0) {
			buf.deleteCharAt(buf.length()-1);
		}
		return baseUrl+buf;
	}

	@Override
	public ControllerDescription routeToController(Request req,
			Response response) {
		String typeAndParams[] = req.getLocalApplicationURL().split("#");
		String typeAndMethod[] = typeAndParams[0].split("\\.");
		String clazz = typeAndMethod[0].replace('/', '.');
		String methodName = typeAndMethod[1];
		String params[] = typeAndParams[1].split(",");
		try {
			Class<?> ctrlClass = Class.forName(clazz);
			Method method = null;
			for (Method m : new DeclaringMethodIterator(ctrlClass)) {
				if(m.getName().equals(methodName) && m.getParameterTypes().length==params.length) {
					method = m;
					break;
				} 
			}
			Object[] paramValues = new Object[params.length];
			int i = 0;
			for (String param : params) {
				paramValues[i] = new PrimitiveTypeBinder().convertPrimitiveType(method.getParameterTypes()[i], param);
				++i;
			}
			return new ControllerDescription(ctrlClass, method, paramValues);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		
	}
}
